package com.example.smssender.contactimport.impl;

import android.content.Context;
import android.net.Uri;
import android.util.Log;
import com.example.smssender.Contact;
import com.example.smssender.contactimport.ContactImporter;
import com.example.smssender.contactimport.ContactImportManager;
import com.example.smssender.contactimport.ImportResult;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Excel 文件导入器
 * 需要添加依赖：
 * implementation 'org.apache.poi:poi:3.17'
 * implementation 'org.apache.poi:poi-ooxml:3.17'
 * 
 * 注意：使用 3.17 版本以兼容 Android API 21+
 * POI 4.x 和 5.x 版本内部使用了 MethodHandle（CleanerUtil），需要 Android API 26+
 */
public class ExcelContactImporter implements ContactImporter {
    
    private static final String TAG = "ExcelContactImporter";
    
    // 静态初始化块：配置 XML 流处理工厂以支持 POI
    static {
        try {
            // 设置系统属性，指定使用 Woodstox 作为 XML 流处理实现
            // 如果没有设置，POI 会尝试查找 com.bea.xml.stream.EventFactory，这在 Android 上不存在
            System.setProperty("javax.xml.stream.XMLEventFactory", 
                "com.ctc.wstx.stax.WstxEventFactory");
            System.setProperty("javax.xml.stream.XMLInputFactory", 
                "com.ctc.wstx.stax.WstxInputFactory");
            System.setProperty("javax.xml.stream.XMLOutputFactory", 
                "com.ctc.wstx.stax.WstxOutputFactory");
            Log.d(TAG, "XML流处理工厂配置完成（使用 Woodstox）");
        } catch (Exception e) {
            Log.w(TAG, "配置XML流处理工厂时出现警告", e);
            // 继续执行，某些 Android 版本可能不需要这些配置
        }
    }
    
    @Override
    public ImportResult importContacts(Context context, Uri source) {
        Log.d(TAG, "importContacts: 开始导入，URI=" + (source != null ? source.toString() : "null"));
        ImportResult result = new ImportResult();
        
        if (source == null) {
            Log.w(TAG, "importContacts: URI为空");
            result.setSuccess(false);
            result.addError("文件URI为空");
            return result;
        }
        
        try {
            Log.d(TAG, "importContacts: 尝试打开文件流");
            InputStream rawInputStream = context.getContentResolver().openInputStream(source);
            if (rawInputStream == null) {
                result.setSuccess(false);
                result.addError("无法打开文件");
                return result;
            }
            
            // 使用 BufferedInputStream 包装，以支持 mark/reset 用于格式检测
            BufferedInputStream inputStream = new BufferedInputStream(rawInputStream);
            
            // 尝试从 URI 获取文件名
            String fileName = getFileNameFromUri(context, source);
            if (fileName == null || fileName.isEmpty()) {
                fileName = source.toString();
            }
            Log.d(TAG, "importContacts: 文件名=" + fileName);
            
            Log.d(TAG, "importContacts: 开始解析Excel文件");
            List<Contact> contacts = parseExcelFile(inputStream, fileName);
            inputStream.close();
            Log.d(TAG, "importContacts: 解析完成，找到 " + contacts.size() + " 条联系人");
            
            // 验证和统计
            List<Contact> validContacts = new ArrayList<>();
            for (Contact contact : contacts) {
                if (ContactImportManager.validateContact(contact)) {
                    validContacts.add(contact);
                } else {
                    result.addError("无效数据：" + (contact.getName() != null ? contact.getName() : "未知"));
                }
            }
            
            result.setTotalCount(contacts.size());
            result.setSuccessCount(validContacts.size());
            result.setFailCount(contacts.size() - validContacts.size());
            result.setContacts(validContacts);
            result.setSuccess(true);
            
        } catch (NoClassDefFoundError e) {
            Log.e(TAG, "importContacts: POI库未找到", e);
            result.setSuccess(false);
            result.addError("Excel导入功能需要添加Apache POI依赖库: " + e.getMessage());
        } catch (Exception e) {
            Log.e(TAG, "importContacts: 解析Excel文件失败", e);
            result.setSuccess(false);
            result.addError("解析Excel文件失败：" + e.getMessage());
            if (e.getCause() != null) {
                result.addError("原因：" + e.getCause().getMessage());
            }
        }
        
        Log.d(TAG, "importContacts: 导入完成，success=" + result.isSuccess() + 
            ", totalCount=" + result.getTotalCount());
        return result;
    }
    
    /**
     * 从 URI 获取文件名
     */
    private String getFileNameFromUri(Context context, android.net.Uri uri) {
        String fileName = null;
        String scheme = uri.getScheme();
        
        if (scheme != null && scheme.equals("content")) {
            try (android.database.Cursor cursor = context.getContentResolver().query(
                    uri, null, null, null, null)) {
                if (cursor != null && cursor.moveToFirst()) {
                    int nameIndex = cursor.getColumnIndex(android.provider.OpenableColumns.DISPLAY_NAME);
                    if (nameIndex != -1) {
                        fileName = cursor.getString(nameIndex);
                    }
                }
            } catch (Exception e) {
                // 忽略错误，使用 URI 字符串作为后备
            }
        }
        
        // 如果无法从 ContentResolver 获取，尝试从 URI 路径提取
        if (fileName == null || fileName.isEmpty()) {
            String path = uri.getPath();
            if (path != null) {
                int lastSlash = path.lastIndexOf('/');
                if (lastSlash >= 0 && lastSlash < path.length() - 1) {
                    fileName = path.substring(lastSlash + 1);
                } else {
                    fileName = path;
                }
            }
        }
        
        return fileName;
    }
    
    /**
     * 解析Excel文件
     */
    private List<Contact> parseExcelFile(BufferedInputStream inputStream, String fileName) throws Exception {
        Log.d(TAG, "parseExcelFile: 开始解析，fileName=" + fileName);
        List<Contact> contacts = new ArrayList<>();
        
        try {
            // 判断文件类型：优先检查文件名
            boolean isXlsx = fileName.toLowerCase().endsWith(".xlsx");
            boolean isXls = fileName.toLowerCase().endsWith(".xls");
            Log.d(TAG, "parseExcelFile: isXlsx=" + isXlsx + ", isXls=" + isXls);
            
            org.apache.poi.ss.usermodel.Workbook workbook;
            
            // 如果明确是 .xls 格式，使用 HSSF
            if (isXls && !isXlsx) {
                Log.d(TAG, "parseExcelFile: 使用 HSSF 解析 .xls 文件");
                workbook = new org.apache.poi.hssf.usermodel.HSSFWorkbook(inputStream);
            } else {
                // 对于 .xlsx 或无法判断的情况，先尝试 XSSF
                // 使用 mark/reset 以便失败时重新尝试 HSSF
                inputStream.mark(8192); // 标记前 8KB，足够检测文件格式
                
                try {
                    // 优先尝试 XSSF（.xlsx 格式）
                    Log.d(TAG, "parseExcelFile: 尝试使用 XSSF 解析 .xlsx 文件");
                    workbook = new org.apache.poi.xssf.usermodel.XSSFWorkbook(inputStream);
                    Log.d(TAG, "parseExcelFile: XSSF 解析成功");
                } catch (Exception e) {
                    Log.w(TAG, "parseExcelFile: XSSF 解析失败，尝试 HSSF", e);
                    // XSSF 失败，可能是 .xls 格式，重置流并尝试 HSSF
                    inputStream.reset();
                    try {
                        Log.d(TAG, "parseExcelFile: 尝试使用 HSSF 解析");
                        workbook = new org.apache.poi.hssf.usermodel.HSSFWorkbook(inputStream);
                        Log.d(TAG, "parseExcelFile: HSSF 解析成功");
                    } catch (Exception e2) {
                        Log.e(TAG, "parseExcelFile: HSSF 也失败", e2);
                        // 两者都失败，抛出更明确的错误
                        String errorMsg = e.getMessage();
                        if (errorMsg != null && errorMsg.contains("Office 2007+ XML") && 
                            errorMsg.contains("OLE2")) {
                            throw new Exception("文件是 Office 2007+ XML 格式（.xlsx），但代码尝试使用 HSSF 解析。这可能是代码错误。");
                        }
                        throw new Exception("无法解析 Excel 文件，请确保文件格式正确（.xls 或 .xlsx）: " + e.getMessage());
                    }
                }
            }
            
            // 读取第一个工作表
            org.apache.poi.ss.usermodel.Sheet sheet = workbook.getSheetAt(0);
            if (sheet == null) {
                workbook.close();
                throw new Exception("工作表为空");
            }
            
            boolean isFirstRow = true;
            int nameIndex = -1;
            int phoneIndex = -1;
            
            for (org.apache.poi.ss.usermodel.Row row : sheet) {
                if (row == null) {
                    continue;
                }
                
                // 读取单元格数据
                List<String> cellValues = new ArrayList<>();
                for (org.apache.poi.ss.usermodel.Cell cell : row) {
                    if (cell == null) {
                        cellValues.add("");
                        continue;
                    }
                    
                    String cellValue = "";
                    // POI 3.17 使用 int 类型的 cellType，而不是 CellType 枚举
                    int cellType = cell.getCellType();
                    if (cellType == org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING) {
                        cellValue = cell.getStringCellValue();
                    } else if (cellType == org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC) {
                        if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) {
                            cellValue = cell.getDateCellValue().toString();
                        } else {
                            // 数字格式，转为字符串
                            double numValue = cell.getNumericCellValue();
                            // 如果是整数，显示为整数；否则显示小数
                            if (numValue == (long) numValue) {
                                cellValue = String.valueOf((long) numValue);
                            } else {
                                cellValue = String.valueOf(numValue);
                            }
                        }
                    } else if (cellType == org.apache.poi.ss.usermodel.Cell.CELL_TYPE_BOOLEAN) {
                        cellValue = String.valueOf(cell.getBooleanCellValue());
                    } else if (cellType == org.apache.poi.ss.usermodel.Cell.CELL_TYPE_FORMULA) {
                        // 对于公式单元格，尝试获取计算后的值
                        try {
                            cellValue = cell.getStringCellValue();
                        } catch (Exception e) {
                            try {
                                double numValue = cell.getNumericCellValue();
                                if (numValue == (long) numValue) {
                                    cellValue = String.valueOf((long) numValue);
                                } else {
                                    cellValue = String.valueOf(numValue);
                                }
                            } catch (Exception e2) {
                                cellValue = cell.getCellFormula();
                            }
                        }
                    } else {
                        cellValue = "";
                    }
                    cellValues.add(cellValue);
                }
                
                if (cellValues.isEmpty()) {
                    continue;
                }
                
                String[] fields = cellValues.toArray(new String[0]);
                
                if (isFirstRow) {
                    // 检测表头
                    nameIndex = findColumnIndex(fields, new String[]{"姓名", "名字", "name", "Name"});
                    phoneIndex = findColumnIndex(fields, new String[]{"手机号", "手机", "电话", "phone", "Phone", "phoneNumber", "mobile"});
                    
                    // 如果找到表头，跳过这一行
                    if (nameIndex >= 0 || phoneIndex >= 0) {
                        isFirstRow = false;
                        continue;
                    } else {
                        // 没有表头，假设第一列是姓名，第二列是手机号
                        nameIndex = 0;
                        phoneIndex = fields.length > 1 ? 1 : 0;
                    }
                    isFirstRow = false;
                }
                
                // 解析联系人数据
                if (fields.length > Math.max(nameIndex, phoneIndex)) {
                    String name = fields[nameIndex].trim();
                    String phone = fields[phoneIndex].trim();
                    
                    // 清理手机号
                    phone = ContactImportManager.normalizePhoneNumber(phone);
                    
                    if (!name.isEmpty() && !phone.isEmpty()) {
                        Contact contact = new Contact(name, phone);
                        contacts.add(contact);
                    }
                }
            }
            
            workbook.close();
            
        } catch (NoClassDefFoundError e) {
            Log.e(TAG, "parseExcelFile: POI库未找到", e);
            throw new Exception("Excel导入功能需要添加Apache POI依赖库: " + e.getMessage());
        } catch (Exception e) {
            Log.e(TAG, "parseExcelFile: 解析失败", e);
            throw e;
        }
        
        Log.d(TAG, "parseExcelFile: 解析完成，共 " + contacts.size() + " 条联系人");
        return contacts;
    }
    
    /**
     * 查找列索引
     */
    private int findColumnIndex(String[] fields, String[] possibleNames) {
        for (int i = 0; i < fields.length; i++) {
            String field = fields[i].trim().toLowerCase();
            for (String name : possibleNames) {
                if (field.equals(name.toLowerCase())) {
                    return i;
                }
            }
        }
        return -1;
    }
    
    @Override
    public String getName() {
        return "Excel文件导入";
    }
    
    @Override
    public String getDescription() {
        return "从Excel文件导入联系人（.xls/.xlsx）";
    }
}

